package com.fingard.dsp.bank.directbank.mhcbc01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqPayRecDetail;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqQrySglBatPayDetail;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.sql.Connection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @author Alon on 2019-10-21.
 * @version 1.0
 */
public class MHCBC01SinglePay extends MHCBC01Base implements ISinglePay {
    private static final String INSERTRECEIPT = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,REQSEQID,BANKREQSEQID) values (?,?,?,?);";
    private static final String SELECTRECEIPT = "SELECT BANKREQSEQID FROM REQSEQIDMAPPING WHERE REQSEQID=? and BANKCODE=?;";

    //单笔支付
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        //返回ATS的对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail tmpRetAtsDetail = new RetAtsSglDetail();
        Connection conn = FGBiz.getLocalDbConn();
        try {
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            writeCommonHeader(xmlWriter);
            xmlWriter.writeStartElement("trn-xfer-rq");
            String seqno = Format.DateTime17SSSFormat.format(new Date()).substring(1);
            xmlWriter.writeElementString("seqno", seqno);
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, p_req1908.reqHeader.bankCode, p_req1908.singleDetail.askNumber, seqno});
            xmlWriter.writeStartElement("xfer-rq");
            xmlWriter.writeElementString("eid", bankFront.org);//企业代码
            xmlWriter.writeElementString("opno", bankFront.operator);//操作员代码
            xmlWriter.writeStartElement("payer_info");
            xmlWriter.writeElementString("payer_actno", p_req1908.singleDetail.payAct);//付款人帐号（外部账号）
            xmlWriter.writeElementString("payer_name", p_req1908.singleDetail.payName, true);//付款人名称
            xmlWriter.writeElementString("payer_province", "", true);//付款人所在省
            xmlWriter.writeElementString("payer_city", "", true);//付款人所在市
            xmlWriter.writeElementString("payer_brname", p_req1908.singleDetail.payBankLocation, true);//付款行名
            xmlWriter.writeElementString("payer_brno", p_req1908.singleDetail.payBankLocationCode, true);//付款行号
            xmlWriter.writeEndElement();//</payer_info>
            xmlWriter.writeStartElement("payee_info");
            xmlWriter.writeElementString("payee_actno", p_req1908.singleDetail.recAct);//收款人帐号
            xmlWriter.writeElementString("payee_name", p_req1908.singleDetail.recName, true);//收款人名称
            xmlWriter.writeElementString("payee_province", "", true);//收款人所在省
            xmlWriter.writeElementString("payee_city", "", true);//收款人所在市
            xmlWriter.writeElementString("payee_brname", p_req1908.singleDetail.cnapsName, true);//收款行名
            xmlWriter.writeElementString("payee_brno", p_req1908.singleDetail.cnapsCode, true);//收款行号
            xmlWriter.writeEndElement();//</payee_info>
            xmlWriter.writeElementString("usage", p_req1908.singleDetail.purpose);//用途
            xmlWriter.writeElementString("curr_type", "RMB");//固定填写“RMB”
            String payAmount = p_req1908.singleDetail.payAmount;
            if (Float.parseFloat(payAmount) > 0) {
                xmlWriter.writeElementString("amount", p_req1908.singleDetail.payAmount.replaceAll("\\.", ""));//没有小数点，精确到分，金额必须大于零
            } else {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = "交易金额必须大于零！";
                retAts.writeRetDetail(tmpRetAtsDetail);
                return retAts;
            }
            xmlWriter.writeElementString("pay_method", "0".equals(p_req1908.singleDetail.sameBnk) ? "1" : "4", true);//(1-大额电汇  3－小额电汇)跨行 4-行内转账
            if ("0".equals(p_req1908.singleDetail.sameBnk)) {
                xmlWriter.writeElementString("pay_func", p_req1908.singleDetail.paySpd, true);//在大额电汇情况下，0-普通，1-加急，目前预留
            } else {
                xmlWriter.writeElementString("pay_func", "", true);
            }
            xmlWriter.writeElementString("vdate", p_req1908.singleDetail.payDate.replaceAll("-", ""));//转账日期
            xmlWriter.writeElementString("rsv1", "", true);//是否需要审核，Y-需要 N-不需要
            xmlWriter.writeElementString("rsv2", "", true);//预留字段2
            xmlWriter.writeElementString("rsv3", "", true);//预留字段3
            xmlWriter.writeEndElement();//</xfer-rq>
            xmlWriter.writeEndDocument();

            String sendReqDate = xmlWriter.toXmlString();
            //签名
            String signResult = sendHttpRequestToSign(sendReqDate);//对报文进行签名
            String sign = "";
            if (signResult != null && signResult.trim().length() > 0) {
                int signBegin = signResult.indexOf("<sign>");
                int signEnd = signResult.indexOf("</sign>");
                sign = signResult.substring(signBegin + 6, signEnd);
                xmlWriter.writeElementString("sign", sign);
                xmlWriter.writeEndDocument();
            } else {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = "获取签名数据失败，请求报文发送失败";
                retAts.writeRetDetail(tmpRetAtsDetail);
                return retAts;
            }

            String[] tmpStrRet = sendToBank(sign);

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRespCode = tmpBkReader.getFirstText("/edes/msg-xdata/trn-xfer-rs/xfer-rs/retcode");
                    tmpRetAtsDetail.respCode = "0";
                    tmpRetAtsDetail.respInfo = convertRespToBank(tmpRespCode);
                    tmpRetAtsDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                    tmpRetAtsDetail.transState = tmpRespCode;
                    tmpRetAtsDetail.payInfoCode = tmpRespCode;
                } else {
                    tmpRetAtsDetail.respCode = "-1";
                    tmpRetAtsDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = tmpStrRet[1];
            }

        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
        } finally {
            conn.close();
        }
        retAts.writeRetDetail(tmpRetAtsDetail);
        return retAts;
    }

    //单笔支付结果查询
    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetAtsDetail = new RetAtsSglDetail();
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        Connection conn = FGBiz.getLocalDbConn();
        try {
            writeCommonHeader(xmlWriter);
            xmlWriter.writeStartElement("trn-xferret-rq");
            xmlWriter.writeElementString("seqno", Format.DateTime17SSSFormat.format(new Date()).substring(1));//银行接口报文长度为16（截去年份）
            xmlWriter.writeStartElement("xferret-rq");
            xmlWriter.writeElementString("eid", bankFront.org);//企业代码
            xmlWriter.writeElementString("opno", bankFront.operator);//操作员代码
            Map<String, Object> map = JDBCHelper.execQuerySingle(conn, SELECTRECEIPT, new Object[]{p_req1944.askNumber, p_req1944.reqHeader.bankCode});
            if (map.size() == 0) {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = "没有这条请求映射的流水号！";
                retAts.writeRetDetail(tmpRetAtsDetail);
                return retAts;
            }
            xmlWriter.writeElementString("oseqno", map.get("BANKREQSEQID").toString());//原转帐指令的流水信息
            xmlWriter.writeEndElement();//</xferret-rq>
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRespCode = tmpBkReader.getFirstText("/edes/msg-xdata/trn-xferret-rs/xferret-rs/retcode");
                    String status = tmpBkReader.getFirstText("/edes/msg-xdata/trn-xferret-rs/xferret-rs/status");
                    if ("0000".equals(tmpRespCode)) {
                        tmpRetAtsDetail.respCode = "0";
                        tmpRetAtsDetail.transState = status + "+" + tmpRespCode;
                        tmpRetAtsDetail.payInfoCode = tmpRetAtsDetail.transState;
                        if ("0".equals(status)) {
                            tmpRetAtsDetail.respInfo = "处理中!";
                        } else if ("1".equals(status)) {
                            tmpRetAtsDetail.respInfo = "记账成功!";
                        } else {
                            tmpRetAtsDetail.respInfo = "记账失败!";
                        }
                    } else {
                        tmpRetAtsDetail.respCode = "-1";
                        tmpRetAtsDetail.respInfo = convertRespToBank(tmpRespCode);
                    }
                } else {
                    tmpRetAtsDetail.respCode = "-1";
                    tmpRetAtsDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception e) {
            tmpRetAtsDetail.respCode = "-1";
            tmpRetAtsDetail.respInfo = e.getMessage();
            e.printStackTrace();
        } finally {
            conn.close();
        }
        retAts.writeRetDetail(tmpRetAtsDetail);
        return retAts;
    }

    //单笔批量（合批）支付
    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        RetAtsSingleBat retAts = new RetAtsSingleBat(p_req1908BAT);
        retAts.reqBatchNO = p_req1908BAT.reqBatchNO;
        retAts.batRespCode = "0";
        retAts.batTransState = "";
        retAts.batPayInfoCode = "";
        while (p_req1908BAT.readRecord()) {
            ReqPayRecDetail tmpDetail = p_req1908BAT.readedDetail;
            ReqSingle req1908 = new ReqSingle(p_req1908BAT.reqHeader);
            req1908.singleDetail = tmpDetail;
            RetAtsSingle eachRet = d_1908_SglPay(req1908);
            retAts.writeRetDetail(eachRet.retDetail);
        }
        retAts.writeAfterDetail();
        return retAts;
    }


    //单笔批量（合批）支付结果查询
    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        RetAtsSingleBat retAts = new RetAtsSingleBat(p_req1944BAT.reqHeader);
        retAts.reqBatchNO = p_req1944BAT.reqBatchNO;
        try {
            retAts.batRespCode = "0";
            retAts.reqBatchNO = p_req1944BAT.reqBatchNO;
            while (p_req1944BAT.readRecord()) {
                ReqQrySglBatPayDetail tmpDetail = p_req1944BAT.readedDetail;
                ReqQrySingle req1944 = new ReqQrySingle(tmpDetail, p_req1944BAT.reqHeader);
                RetAtsSingle resp1944 = d_1944_QrySglPay(req1944);
                retAts.writeRetDetail(resp1944.retDetail);
            }
        } catch (Exception ex) {
            WriteBankLogLn(ex);
            retAts = new RetAtsSingleBat(p_req1944BAT.reqHeader);
            retAts.batRespCode = "-1";
            retAts.batRespInfo = ex.getMessage();
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}
